package de.fuberlin.inf.alp3.ue02;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class GUI
{
    private JFrame f;
    private Drawable drawable;
    private Reservable reservable;
    private JTextField rowFld = new JTextField(5);
    private JTextField seatFromFld = new JTextField(5);
    private JTextField seatToFld = new JTextField(5);
    
    public GUI(String title, Object drawableReservable)
    {
        if (title == null)
            title = "GUI";
        if (drawableReservable == null)
            throw new RuntimeException("second parameter is null!");
        if (
                (drawableReservable instanceof Drawable) &&
                (drawableReservable instanceof Reservable)) {
            drawable = ((Drawable)drawableReservable);
            reservable = ((Reservable)drawableReservable);
            setupGui(title, drawable.getWidth(),drawable.getHeight());
        } else {
            throw new RuntimeException("second parameter does not implement " +
            		"Drawable and Reservable!");
        }
    }
    
    private void setupGui(String title, int width, int height) {
        this.f = new JFrame(title);
        this.f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                GUI.this.f.setVisible(false);
                GUI.this.f.dispose();
            }
        });
        GUI.DrawingPanel p = new GUI.DrawingPanel(width, height);
        this.f.getContentPane().add("Center", p);
        JPanel fields = new JPanel();
        GridLayout gl = new GridLayout(3, 2);
        gl.setHgap(3);
        gl.setVgap(3);
        fields.setLayout(gl);
        fields.add(new JLabel("Row:"));
        fields.add(this.rowFld);
        fields.add(new JLabel("Seats from: "));
        fields.add(this.seatFromFld);
        fields.add(new JLabel("to: "));
        fields.add(this.seatToFld);
        JPanel buttons = new JPanel();
        buttons.setLayout(new GridLayout(2, 1));
        JButton reserve = new JButton("Reserve");
        reserve.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                GUI.this.performReservation();
            }
        });
        buttons.add(reserve);
        JButton cancel = new JButton("Cancel");
        cancel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                GUI.this.performCancellation();
            }
        });
        buttons.add(cancel);
        JPanel controls = new JPanel();
        controls.add(fields);
        controls.add(buttons);
        this.f.getContentPane().add("South", controls);
        this.f.getRootPane().setDefaultButton(reserve);
        this.f.pack();
        this.f.setVisible(true);
    }
    private void performReservation() {
        char row = '0';
        int from = -1;
        int to = -1;
        try {
            if (this.rowFld.getText().length() == 1)
                row = this.rowFld.getText().toLowerCase().charAt(0);
            from = Integer.parseInt(this.seatFromFld.getText());
            to = Integer.parseInt(this.seatToFld.getText());
            if (
                    ('a' > row) || (row > this.reservable.getMaxRow()) ||
                    (from <= 0) || (from > this.reservable.getMaxSeat()) ||
                    (to <= 0) || (to > this.reservable.getMaxSeat()) ||
                    (from > to))
                throw new Exception();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this.f, 
                    "Please check your input values.", "Error", 0);
            return;
        }
        if (this.reservable.reserve(row, from, to)) {
            this.f.repaint();
            JOptionPane.showMessageDialog(this.f, 
            "The reservation was successful.", 
            "Reservation successful", -1);
        } else {
            JOptionPane.showMessageDialog(this.f,
                    "Reservation failed. Seat(s) not available.",
                    "Reservation failed", 2);
        }
    }
    private void performCancellation() {
        char row = '0';
        int from = -1;
        int to = -1;
        try {
            if (this.rowFld.getText().length() == 1)
                row = this.rowFld.getText().toLowerCase().charAt(0);
            from = Integer.parseInt(this.seatFromFld.getText());
            to = Integer.parseInt(this.seatToFld.getText());
            if (
                    ('a' > row) || (row > this.reservable.getMaxRow()) ||
                    (from <= 0) || (from > this.reservable.getMaxSeat()) ||
                    (to <= 0) || (to > this.reservable.getMaxSeat()) ||
                    (from > to))
                throw new Exception();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this.f,
                    "Please check your input values.", "Error", 0);
            return;
        }
        if (this.reservable.cancel(row, from, to)) {
            this.f.repaint();
            JOptionPane.showMessageDialog(this.f, 
            "The cancellation was successful.", 
            "Cancellation successful", -1);
        } else {
            JOptionPane.showMessageDialog(this.f, "Cancellation failed.", 
            "Cancellation failed", 2);
        }
    }
    private class DrawingPanel extends JPanel
    {
        private static final long serialVersionUID = 1L;
        DrawingPanel(int paramInt1, int paramInt2) {
            setPreferredSize(new Dimension(paramInt1, paramInt2));
        }
        public void paint(Graphics g) {
            GUI.this.drawable.draw(g);
        }
    }
}